package kr.co.hk.local;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import kr.co.hk.R;
import kr.co.hk.util.MapUtil;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class LocalLocationMapView extends MapActivity {
	private MapView mapView; // 맵뷰 객체
	private MapController mapController; // 맵을 줌시키거나, 이동시키는데 사용될 컨트롤러
	private ArrayList<LocalInfo> items;
	private String addrSplit = "";
	private String nQuery = "";
	private int totCnt = 0;
	private int start = 0; // naver search start count
	private int display = 0; // naver search display count
	private ProgressDialog progressDialog;
	final private int PROGRESS_DIALOG = 0;
	private LocalItemizedOverlay itemizedOverlay;
	private Location currentLocation; // 현재 위치
	private MapUtil mapUtil;
	private boolean pageEx = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.local_map_view);

		Button button = (Button) findViewById(R.id.btnSatellite);

		Bundle extra = getIntent().getExtras();
		addrSplit = extra.getString("addrSplit");
		nQuery = extra.getString("nQuery");

		currentLocation = new Location("reverseGeocoded");
		currentLocation.setLatitude(extra.getDouble("currentLocationLat"));
		currentLocation.setLongitude(extra.getDouble("currentLocationLng"));

		mapView = (MapView) findViewById(R.id.gMapView);
		mapView.setBuiltInZoomControls(true);
		mapView.setSatellite(false);

		mapController = mapView.getController();

		mapUtil = new MapUtil();
		items = new ArrayList<LocalInfo>();
		start = 1;
		display = 10;

		items.clear();
		threadStart();

		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {

				if (totCnt == items.size()) {
					toast(nQuery + "  검색  결과가  더 이상 없습니다.");
				} else {
					int nextStart = start + display;
					start = nextStart;
					childThread();

				}

			}
		});

	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	private void threadStart() {
		pageEx = false;
		showDialog(PROGRESS_DIALOG);
		new Thread() {
			public void run() {
				NaverLocalSearch(addrSplit, nQuery, start, display);
				nextSearch();
				Message msg = handler.obtainMessage();
				handler.sendMessage(msg);
			}
		}.start();
	}

	private void childThread() {
		pageEx = false;
		showDialog(PROGRESS_DIALOG);
		new Thread() {
			public void run() {
				NaverLocalSearch(addrSplit, nQuery, start, display);
				nextSearch();
				Message msg = handler.obtainMessage();
				handler.sendMessage(msg);
			}
		}.start();
	}

	final Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			progressDialog.dismiss();
			LocalLocationMapView.this.removeDialog(PROGRESS_DIALOG);
			if (pageEx) {
				excePro();
			} else {
				mapOverlay();
				toast(nQuery + "  검색 결과 : " + items.size());
			}
			super.handleMessage(msg);
		}
	};

	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case PROGRESS_DIALOG:
			progressDialog = new ProgressDialog(this);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			progressDialog.setMessage("Now loading..");
			progressDialog.setIndeterminate(true);
			progressDialog.setCancelable(false);
			return progressDialog;

		}
		return null;

	}

	private void mapOverlay() {

		List<Overlay> mapOverlays = mapView.getOverlays();

		Drawable marker = getResources().getDrawable(R.drawable.bubble);
		marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker
				.getIntrinsicHeight());

		GeoPoint myPoint = new GeoPoint(
				(int) (currentLocation.getLatitude() * 1E6),
				(int) (currentLocation.getLongitude() * 1E6));

		itemizedOverlay = new LocalItemizedOverlay(marker, this, mapView,
				myPoint);

		LocalInfo my_li = new LocalInfo("내 현재 위치", "", "", "", currentLocation);
		itemizedOverlay.addMy(my_li);
		if (items.size() == 0) {
			OverlayItem myoverlayitem = new OverlayItem(myPoint, my_li
					.getTitle(), my_li.getDistance());
			itemizedOverlay.addOverlay(myoverlayitem);
		} else {

			for (int i = 0; i < items.size(); i++) {
				LocalInfo li = items.get(i);

				GeoPoint geoPoint = new GeoPoint(
						(int) (li.getLocationLat() * 1E6), (int) (li
								.getLocationLng() * 1E6));

				OverlayItem overlayitem = new OverlayItem(geoPoint, li
						.getTitle(), li.getDistance());
				itemizedOverlay.addList(li);
				itemizedOverlay.addOverlay(overlayitem);

			}
		}

		mapOverlays.add(itemizedOverlay);
		mapView.getOverlays().add(itemizedOverlay);
		mapView.getController().setZoom(15);
		mapView.getController().animateTo(myPoint);
		mapView.postInvalidate();

	}

	private void NaverLocalSearch(String local, String query, int start,
			int display) {

		String name = local + " " + query;
		String encode = "";
		String key = "e3c6660e11008c5a862835390d2ed309";

		try {
			encode = URLEncoder.encode(name, "utf-8");
			String html = "http://openapi.naver.com/search?key=" + key
					+ "&query=" + encode + "&target=local&start=" + start
					+ "&display=" + display;

			URL url = new URL(html);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			if (conn != null) {
				conn.setConnectTimeout(10000);
				conn.setReadTimeout(10000);
				conn.setUseCaches(false);
				if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
					BufferedReader br = new BufferedReader(
							new InputStreamReader(conn.getInputStream(),
									"utf-8"));

					XmlPullParserFactory factory = XmlPullParserFactory
							.newInstance();
					factory.setNamespaceAware(true);
					XmlPullParser xpp = factory.newPullParser();
					xpp.setInput(br);
					int eventType = xpp.getEventType();
					String tag = "";
					String title = "";
					String link = "";
					String telephone = "";
					String mapx = "";
					String mapy = "";
					while (eventType != XmlPullParser.END_DOCUMENT) {
						if (eventType == XmlPullParser.START_TAG) {
							tag = xpp.getName();

							if ("total".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									totCnt = Integer.parseInt(xpp.getText());
								}
							} else if ("title".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									title = xpp.getText().replace("<b>", "")
											.replace("</b>", "");
								}

							} else if ("link".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									link = xpp.getText();

								}
							} else if ("telephone".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									telephone = xpp.getText();
								}
							} else if ("mapx".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									mapx = xpp.getText();
								}
							} else if ("mapy".equals(tag)) {
								eventType = xpp.next();
								if (eventType == XmlPullParser.TEXT) {
									mapy = xpp.getText();

									String[] xy = mapUtil.getDaumLatLng(mapx,
											mapy).split(",");
									double lng = Double.parseDouble(xy[0]);
									double lat = Double.parseDouble(xy[1]);

									Location findLocation = new Location(
											"reverseGeocoded");
									findLocation.setLatitude(lat);
									findLocation.setLongitude(lng);
									double distance = mapUtil.getDistanceTo(
											findLocation, currentLocation);

									LocalInfo info = new LocalInfo(title, link,
											telephone, " ("
													+ String.format("%.2f",
															distance) + "km)",
											findLocation);
									items.add(info);

								}

							}

						}
						eventType = xpp.next();

					}
					br.close();

				}
				conn.disconnect();
			}

		} catch (MalformedURLException e) {
			pageEx = true;
			e.printStackTrace();
		}

		catch (XmlPullParserException e) {
			pageEx = true;
			e.printStackTrace();
		}

		catch (IOException e) {
			pageEx = true;
			e.printStackTrace();
		}
	}

	private void nextSearch() {
		if (totCnt > items.size()) {
			int nextStart = start + display;
			start = nextStart;
			NaverLocalSearch(addrSplit, nQuery, start, display);
		}

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			pageEx = true;
			e.printStackTrace();
		}

	}

	private void toast(String text) {
		Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
	}

	private void excePro() {
		toast("페이지 로딩시 오류가  있습니다. \n 네트워크 확인 후 다시 시도 하세요!");
		onBackPressed();
	}

}
